import java.lang.annotation.Annotation;
import java.lang.reflect.*;
import java.util.Arrays;

public class ReflectionDemo {
    public static void main(String[] args) {
        System.out.println("🔍 Java反射演示 - Person类分析");
        System.out.println("=".repeat(50));

        try {
            // 获取Class对象
            Class<?> personClass = Person.class;

            // 类信息
            showClassInfo(personClass);

            // 字段信息
            showFieldInfo(personClass);

            // 方法信息
            showMethodInfo(personClass);

            // 构造器信息
            showConstructorInfo(personClass);

            // 私有访问演示
            showPrivateAccess(personClass);

            // 注解读取
            showAnnotationInfo(personClass);

            // 父类与接口
            showInheritanceInfo(personClass);

            // 包信息
            showPackageInfo(personClass);

            // 修饰符
            showModifierInfo(personClass);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 📦 类信息
    private static void showClassInfo(Class<?> clazz) {
        System.out.println("\n 类信息:");
        System.out.println("类名: " + clazz.getName());
        System.out.println("简单类名: " + clazz.getSimpleName());
        System.out.println("规范类名: " + clazz.getCanonicalName());
        System.out.println("是否为接口: " + clazz.isInterface());
        System.out.println("是否为数组: " + clazz.isArray());
        System.out.println("是否为基本类型: " + clazz.isPrimitive());
    }

    // 🧱 字段信息
    private static void showFieldInfo(Class<?> clazz) {
        System.out.println("\n 字段信息:");
        Field[] fields = clazz.getDeclaredFields();
        System.out.println("字段数量: " + fields.length);

        for (Field field : fields) {
            System.out.println("字段名: " + field.getName());
            System.out.println("  类型: " + field.getType().getSimpleName());
            System.out.println("  修饰符: " + Modifier.toString(field.getModifiers()));
            System.out.println("  是否为私有: " + Modifier.isPrivate(field.getModifiers()));
            System.out.println("  是否为公共: " + Modifier.isPublic(field.getModifiers()));
            System.out.println();
        }
    }

    // 🛠 方法信息
    private static void showMethodInfo(Class<?> clazz) {
        System.out.println("\n 方法信息:");
        Method[] methods = clazz.getDeclaredMethods();
        System.out.println("方法数量: " + methods.length);

        for (Method method : methods) {
            System.out.println("方法名: " + method.getName());
            System.out.println("  返回类型: " + method.getReturnType().getSimpleName());
            System.out.println("  参数类型: " + Arrays.toString(method.getParameterTypes()));
            System.out.println("  修饰符: " + Modifier.toString(method.getModifiers()));
            System.out.println("  是否为私有: " + Modifier.isPrivate(method.getModifiers()));
            System.out.println("  是否为公共: " + Modifier.isPublic(method.getModifiers()));
            System.out.println();
        }
    }

    // 🧱 构造器信息
    private static void showConstructorInfo(Class<?> clazz) {
        System.out.println("\n 构造器信息:");
        Constructor<?>[] constructors = clazz.getDeclaredConstructors();
        System.out.println("构造器数量: " + constructors.length);

        for (Constructor<?> constructor : constructors) {
            System.out.println("构造器: " + constructor.getName());
            System.out.println("  参数类型: " + Arrays.toString(constructor.getParameterTypes()));
            System.out.println("  修饰符: " + Modifier.toString(constructor.getModifiers()));
            System.out.println("  参数数量: " + constructor.getParameterCount());
            System.out.println();
        }
    }

    // 🔒 私有访问演示
    private static void showPrivateAccess(Class<?> clazz) throws Exception {
        System.out.println("\n 私有访问演示:");

        // 创建Person实例
        Person person = new Person("张三", 25);
        System.out.println("原始对象: " + person);

        // 获取私有字段
        Field nameField = clazz.getDeclaredField("name");
        Field ageField = clazz.getDeclaredField("age");

        // 设置可访问
        nameField.setAccessible(true);
        ageField.setAccessible(true);

        // 读取私有字段值
        String name = (String) nameField.get(person);
        int age = (int) ageField.get(person);
        System.out.println("通过反射读取私有字段 - name: " + name + ", age: " + age);

        // 修改私有字段值
        nameField.set(person, "李四");
        ageField.set(person, 30);
        System.out.println("通过反射修改私有字段后: " + person);

        // 调用私有方法
        Method sayHelloMethod = clazz.getDeclaredMethod("sayHello", String.class);
        sayHelloMethod.setAccessible(true);
        System.out.print("调用私有方法: ");
        sayHelloMethod.invoke(person, "Hello");
    }

    // 🏷 注解读取
    private static void showAnnotationInfo(Class<?> clazz) {
        System.out.println("\n\n 注解读取:");

        // 类上的注解
        Annotation[] classAnnotations = clazz.getAnnotations();
        System.out.println("类上的注解数量: " + classAnnotations.length);
        for (Annotation annotation : classAnnotations) {
            System.out.println("  注解: " + annotation.annotationType().getSimpleName());
        }

        // 方法上的注解
        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            Annotation[] methodAnnotations = method.getAnnotations();
            if (methodAnnotations.length > 0) {
                System.out.println("方法 '" + method.getName() + "' 上的注解:");
                for (Annotation annotation : methodAnnotations) {
                    System.out.println("  " + annotation.annotationType().getSimpleName());
                }
            }
        }
    }

    // 🧬 父类与接口
    private static void showInheritanceInfo(Class<?> clazz) {
        System.out.println("\n 父类与接口:");

        // 父类
        Class<?> superClass = clazz.getSuperclass();
        System.out.println("父类: " + (superClass != null ? superClass.getSimpleName() : "无"));

        // 接口
        Class<?>[] interfaces = clazz.getInterfaces();
        System.out.println("实现的接口数量: " + interfaces.length);
        for (Class<?> interfaceClass : interfaces) {
            System.out.println("  接口: " + interfaceClass.getSimpleName());
        }
    }

    // 📦 包信息
    private static void showPackageInfo(Class<?> clazz) {
        System.out.println("\n 包信息:");
        Package pkg = clazz.getPackage();
        if (pkg != null) {
            System.out.println("包名: " + pkg.getName());
            System.out.println("包标题: " + pkg.getImplementationTitle());
            System.out.println("包版本: " + pkg.getImplementationVersion());
        } else {
            System.out.println("默认包");
        }
    }

    // 🛑 修饰符
    private static void showModifierInfo(Class<?> clazz) {
        System.out.println("\n 修饰符:");
        int modifiers = clazz.getModifiers();
        System.out.println("类修饰符: " + Modifier.toString(modifiers));
        System.out.println("是否为公共: " + Modifier.isPublic(modifiers));
        System.out.println("是否为抽象: " + Modifier.isAbstract(modifiers));
        System.out.println("是否为最终: " + Modifier.isFinal(modifiers));
        System.out.println("是否为静态: " + Modifier.isStatic(modifiers));
    }
}